﻿using System;
using System.Linq;
using System.Windows.Forms;
using DesignerHelper.Main;
using SpreadsheetGear;
using DesignerHelper.Help;

namespace WorkbookDesigner.Addons.DefineName
{
    public partial class DefineFromSelectionDialog : Form
    {

        private IWorkbook AffectedBook { get; set; }
        private IWorksheet AffectedSheet { get; set; }
        private IRange AffectedRange { get; set; }
        private LockBookWorker LbwTrigger { get; set; }
        private DefineFromSelectionDialog()
        {
            InitializeComponent();
        }

        public DefineFromSelectionDialog(IRange rangeSelection) : this()
        {
            TriggerInit(rangeSelection);
        }
        public void TriggerInit(IRange rangeIn)
        {
            AffectedRange = rangeIn;
            AffectedSheet = AffectedRange.Worksheet;
            AffectedBook = AffectedSheet.Workbook;
            LbwTrigger = LockBookWorker.GetWorker(AffectedRange);
            LbwTrigger.DoWork(() => InitRangeList(AffectedBook));
            CheckAvailable(AffectedRange);

        }


        private bool ToDefineFirstRow => checkBoxFirstRow.Checked;

        private bool ToDefineLastRow => checkBoxLastRow.Checked;

        private bool ToDefineLeftColumn => checkBoxLeftColumn.Checked;

        private bool ToDefineRightColumn => checkBoxRightColumn.Checked;

        private bool ToDefineInWorkbook => comboBoxAffectRange.SelectedIndex == 0;


        private void CheckAvailable(IRange range)
        {
            if (range.RowCount < 2)
            {
                checkBoxFirstRow.Enabled = false;
                checkBoxLastRow.Enabled = false;
            }
            if (range.ColumnCount < 2)
            {
                checkBoxLeftColumn.Enabled = false;
                checkBoxRightColumn.Enabled = false;
            }
        }
        private void InitRangeList(IWorkbook workbook)
        {
            comboBoxAffectRange.Items.Clear();
            object[] o = new object[workbook.Worksheets.Count + 1];
            o[0] = workbook.Name;
            for (int i = 0; i < workbook.Worksheets.Count; i++)
            {
                o[i + 1] = workbook.Worksheets[i].Name;
            }
            comboBoxAffectRange.Items.AddRange(o);
            comboBoxAffectRange.SelectedIndex = 0;
        }

        #region Main Business

        private void AddName()
        {
            LbwTrigger.DoWork(() =>
            {
                INames names = GetINames();
                IRange allRows = AffectedRange.Rows;
                IRange allColumns = AffectedRange.Columns;

                if (ToDefineFirstRow)
                    DefineFirstRow(allColumns, names);

                if (ToDefineLastRow)
                    DefineLastRow(allColumns, names);

                if (ToDefineLeftColumn)
                    DefineLeftColumn(allRows, names);

                if (ToDefineRightColumn)
                    DefineRightColumn(allRows, names);


            });
        }

        private void DefineLeftColumn(IRange allRows, INames names)
        {
            DefineName(allRows, names, row => row.Cells[0, 0]);
        }

        private void DefineFirstRow(IRange allColumns, INames names)
        {
            DefineName(allColumns, names, column => column.Cells[0, 0]);
        }

        private void DefineRightColumn(IRange allRows, INames names)
        {
            DefineName(allRows, names, row => row.Cells[0, row.ColumnCount - 1]);
        }

        private void DefineLastRow(IRange allColumns, INames names)
        {
            DefineName(allColumns, names, column => column.Cells[column.RowCount - 1, 0]);
        }

        private void DefineName(IRange rangeIn, INames names, Func<IRange, IRange> getNameCell)
        {
            foreach (IRange range in rangeIn)
            {
                IRange firstCell = getNameCell(range);
                IRange afterRange = range.Subtract(firstCell);
                string formula = GetAddressOfRange(afterRange);
                string name = firstCell.Text;

                if (string.IsNullOrEmpty(name))
                {
                    MesBox.ErrorMessage("名称不能为空！");
                    continue;
                };
                if (Helper.ValidateName(names, name))
                    names.Add(name, formula, ReferenceStyle.A1);
            }
        }

        private string GetAddressOfRange(IRange afterRange)
        {
            return "=" + afterRange.GetAddress(true, true, ReferenceStyle.A1, true, null);
        }

        private INames GetINames()
        {
            return ToDefineInWorkbook ? AffectedBook.Names : AffectedSheet.Names;
        }

        #endregion





        private void buttonCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void comboBoxAffectRange_SelectedIndexChanged(object sender, EventArgs e)
        {
            int i = comboBoxAffectRange.SelectedIndex;
            LbwTrigger.DoWork(() =>
            {
                AffectedSheet = i > 0 ? AffectedBook.Worksheets[i - 1] : AffectedBook.ActiveWorksheet;
            });

        }

        private void buttonOK_Click(object sender, EventArgs e)
        {
            AddName();
            Close();
        }
    }
}
